﻿using System.Linq;
using System.Web;
using App_Code.Helpers;
using App_Code.Objects;
using DotNetOpenAuth.OpenId.RelyingParty;

namespace App_Code.Logic
{
    /// <summary>
    /// Summary description for SessionLogic
    /// </summary>
    public class SessionLogic
    {
        #region Public methods
        public static void SessionStarted(string sessionId)
        {
            var session = VisualCronLogic.AddSession(sessionId);

            PageHelper.VisualCronSession = session;
        }

        public static void SessionFinished(string sessionId)
        {
            VisualCronLogic.RemoveSession(sessionId);
        }

        public static void SessionAuthenticatedOpenAuth(VisualCronSession session, string id, string displayName = null)
        {
            LinkProfile(session, id, displayName ?? id);
        }

        public static void SessionAuthenticatedOpenId(VisualCronSession session, OpenIdEventArgs args)
        {
            LinkProfile(session, args.ClaimedIdentifier, args.Response.FriendlyIdentifierForDisplay);
        }

        public static void SessionSave(VisualCronSession session)
        {
            if (session.Profile == null)
                return;

            session.Profile.Connections.Clear();

            session.Profile.Connections.AddRange(session.Connections);

            UserProfileLogic.Save(session.Profile);
        }

        public static void SessionAuthenticationRemove(VisualCronSession session)
        {
            session.Profile = null;
            VisualCronLogic.CloseConnections(session);

            session.Connections = null; // on next request a list with default connection will be returned
        }

        public static void ProfileConnectionsToSession(VisualCronSession session)
        {
            if (session.Profile.Connections != null)
            {
                foreach (var connection in session.Profile.Connections)
                {
                    // we only add unique connections, not to have duplicates in list
                    if (!session.Connections.Exists(con => con.Equals(connection)))
                    {
                        session.Connections.Add(new VCConnection(connection));
                    }
                }

                // we also remove those session connections, which aren't connected and aren't contained in new profile (i.e. were deleted in another session)
                foreach (var connection in session.Connections.ToList()) 
                    // ToList() creates a copy of list through which we iterate, while removing items from original collection
                {
                    if (!connection.Connected && (!session.Profile.Connections.Exists(con => con.Equals(connection))))
                    {
                        session.Connections.Remove(connection);
                    }
                }
            }
        }

        #endregion

        #region Private methods

        private static void LinkProfile(VisualCronSession session, string uniqueId, string userFriendlyId)
        {
            var profile = UserProfileLogic.FindByIdOrCreate(uniqueId, userFriendlyId);

            session.Profile = profile;

            ProfileConnectionsToSession(session);
        }
        #endregion
    }
}